package com.body.park.user.business;

import cn.hutool.json.JSONUtil;
import com.body.park.user.bloom.BloomFilterHelper;
import com.body.park.user.bloom.RedisBloomFilter;
import com.body.park.user.client.UserTestService;
import com.body.park.user.client.model.Order;
import com.body.park.user.config.RedisSonConfiguration;
import com.google.common.hash.Funnels;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Author chaoxian.wu
 * @DATE 2022/3/13 20:32
 */
@DubboService
@Component
@Slf4j
public class UserTestServiceImpl implements UserTestService {

    private static int count = 20;

//    @DubboReference
//    private OrderTestService orderTestService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisBloomFilter redisBloomFilter;

    @Autowired
    private RedisSonConfiguration redisSonConfiguration;

    private RBloomFilter<Long> bloomFilter;

    @PostConstruct
    public void init() {
        bloomFilter = redisSonConfiguration.bloomFilter();
    }

    @Override
    public String test() {
//        String orderInfo = orderTestService.getOrderInfo();
//        System.out.println("======" + orderInfo);
        return null;
    }

//    public void findById(Long id) {
//        TUser user = itUserService.selectById(id);
//        log.info("user is:{}", JSONUtil.toJsonStr(user));
//    }

    @Override
    public String findRedisKey(String key) {
        Object result = redisTemplate.opsForValue().get(key);
        if(StringUtils.isEmpty(result)) {
            return "fail";
        }
        return result.toString();
    }

    @Override
    public String setRedisKey(String key, String value) {
        value = "value:" + value;
        redisTemplate.opsForValue().set(key, value, 1000, TimeUnit.SECONDS);
        return value;
    }

    /**
     * 测试分布式锁
     */
    @Override
    public String testRedisSon() {
        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread(new Runnable() {

                @Override
                public void run() {
                    RLock lock = redissonClient.getLock("test-lock");
                    try {
                        if (lock.tryLock(1000, 1000, TimeUnit.SECONDS)) {
                            if (count <= 0) {
                                throw new RuntimeException("商品已经卖完了，下次再来吧！");
                            }
                            System.out.println("count的值：" + count--);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }
            });
            thread.start();
        }
        return "success";
    }

    @Override
    public boolean addBloomFilterData(String value) {
        //增加数据
        int expectedInsertions = 1000;
        double fpp = 0.02;
        redisBloomFilter.delete("bloom");
        BloomFilterHelper<CharSequence> bloomFilterHelper = new BloomFilterHelper<>(Funnels.stringFunnel(Charset.defaultCharset()), expectedInsertions, fpp);
        List<CharSequence> valueList = new ArrayList<>();
        for (int i = 1; i <= 100; i++) {
            valueList.add(i + "");
        }
        long beginTime = System.currentTimeMillis();
        redisBloomFilter.addList(bloomFilterHelper, "bloom", valueList);
        long costMs = System.currentTimeMillis() - beginTime;
        System.out.println("布隆过滤器添加值，耗时:" + costMs);
//        redisBloomFilter.isExists(bloomFilterHelper, "bloom", value)；
        return true;
    }

    @Override
    public boolean checkBloomFilterData(Long value) {
        boolean flag = bloomFilter.contains(value);
        log.info("值：{}，是否存在布隆过滤器中：{}", value, flag);
        return flag;
    }

    public static void main(String[] args) {
        List<Order> orderList = new ArrayList<>();
        Order o1 = new Order();
        o1.setId("1");
        o1.setName("aaa");
        o1.setBind(true);
        orderList.add(o1);
        Order o2 = new Order();
        o2.setName("bbb");
        o2.setBind(false);
        orderList.add(o2);
        Order o3 = new Order();
        o3.setName("ccc");
        o3.setBind(true);
        orderList.add(o3);
        Order o4 = new Order();
        o4.setId("2");
        o4.setName("ddd");
        o4.setBind(false);
        orderList.add(o4);
        orderList.stream().filter(order -> Objects.nonNull(order.getId()) && order.isBind()).forEach(order -> {
            System.out.println("===" + JSONUtil.toJsonStr(order));
        });
        System.out.println("======" + JSONUtil.toJsonStr(orderList));
    }
}
